package nexus.criterios.exp;

import java.util.*;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.swing.JOptionPane;
import nexus.criterios.CriterioEvaluacion;
import nexus.criterios.GestorCriteriosDB;


public class ControlFormula implements KeyListener{
    private String formula;
    private String variable;
    private Stack<String> memento;
    private String style;
    private String criterio;
    private String nombreCriterio;
    private String styleMesage;
    private HashMap<String,String> subcriterios;
    public ControlFormula(){
        formula="";
        memento=new Stack<String>();
    }
    public String getTitulo(){
        return nombreCriterio ;
    }
    public void init(String criterio){
        this.criterio=criterio;
        String f=GestorCriteriosDB.getInstance().recuperarFormula(criterio);
        nombreCriterio=GestorCriteriosDB.getInstance().recuperarCriterioEvaluacion(criterio).getNombreCriterio();
        if(f==null){
            formula="";
        }else{
            formula=f;
        }
        memento=new Stack<String>();
        
    }
    
    public ArrayList<SelectItem> getCriterios(){
        subcriterios=new HashMap<String, String>();
        //JOptionPane.showMessageDialog(null,criterio);
        CriterioEvaluacion ce=GestorCriteriosDB.getInstance().recuperarCriterioEvaluacion(criterio);
        ArrayList<SelectItem> items=new ArrayList<SelectItem>();
        for(CriterioEvaluacion x : ce.getSubcriterios()){
            if(x.isConfigurado()){
                items.add(new SelectItem(x.getCodigoCriterio(),x.getNombreCriterio()));
                subcriterios.put(x.getCodigoCriterio(),x.getNombreCriterio());
            }
        }
        return items;
    }
    
    public void selectCriterio(ValueChangeEvent ve){
        variable=(String) ve.getNewValue();
        /*if(variable!=null&&variable.compareTo("")!=0){
            memento.push(formula+"");
            formula+=subcriterios.get(variable);
        }*/
    }
    public void agregarCriterio(ActionEvent ae){
        memento.push(formula+"");
        formula+=subcriterios.get(variable);
        
    }
    public KeyWord getKeyWord(){
        return new KeyWord(this);
    }
    public void clickNumero(int n) {
        memento.push(formula+"");
        formula+=n;
    }

    public void clickOperador(char o) {
        memento.push(formula+"");
        formula+=o;
    }
    public void clickMax() {
        memento.push(formula+"");
        formula+="MAX[";
    }
    public String getExpresion(){
        return formula;
    }
    public String getMaxValor(){
        String res="";
        double min=minimoValores();
        double max=maximoValores();
        if(min>max){
            res+=min;
        }else{
            res+=max;
        }
        return res;
    }
    public String getMinValor(){
        String res="";
        double min=minimoValores();
        double max=maximoValores();
        if(min>max){
            res+=max;
        }else{
            res+=min;
        }
        return res;
    }
    public double minimoValores(){
        CriterioEvaluacion ce=GestorCriteriosDB.getInstance().recuperarCriterioEvaluacion(criterio);
        HashMap<String,Double> var=new HashMap<String, Double>();
        for(CriterioEvaluacion c : ce.getSubcriterios()){
            if(c.isConfigurado()){
                var.put(c.getNombreCriterio(),c.minimoValor());
            }
        }
        Expresion exp=new Expresion(var,formula);
        double res=0;
        try{
            res=exp.evaluar();
        }catch(Exception e){}
        return res;
    }
    public double maximoValores(){
        CriterioEvaluacion ce=GestorCriteriosDB.getInstance().recuperarCriterioEvaluacion(criterio);
        HashMap<String,Double> var=new HashMap<String, Double>();
        for(CriterioEvaluacion c : ce.getSubcriterios()){
            if(c.isConfigurado()){
                var.put(c.getNombreCriterio(),c.maximoValor());
            }
        }
        Expresion exp=new Expresion(var,formula);
        double res=0;
        try{
            res=exp.evaluar();
        }catch(Exception e){
  //          JOptionPane.showMessageDialog(null,e.getClass().getCanonicalName());
        }
        return res;
    }
    public String getStyle(){
        return "";
    }
    public String getMensajeError(){
        String msg="";
        CriterioEvaluacion ce=GestorCriteriosDB.getInstance().recuperarCriterioEvaluacion(criterio);
        HashMap<String,Double> variables=new HashMap<String,Double>();
        for(CriterioEvaluacion x : ce.getSubcriterios()){
            variables.put(x.getNombreCriterio(),2.0);
        }
        Expresion exp=new Expresion(variables,formula);
        try {
            exp.evaluar();
        } catch (ErrorDeSintaxisExpresion ex) {
            return "Error de Sintaxis";
        } catch (FaltaComa ex) {
            return "Falta una Coma";
        } catch (FaltaAbre ex) {
            return "Falta una llave de apertura";
        } catch (FaltaOperador ex) {
            return "Falta un operador";
        } catch(ExpresionIncompleta ei){
            return "Funcion Incompleta";
        } catch(Exception e1){
            return "Error de Sintaxis";
        }
        return msg;
    }

    public void clickCL() {
        formula="";
        
        memento=new Stack<String>();
        
    }
    public void clickCE() {
        if(!memento.isEmpty())
            formula=memento.pop();
        
    }
    public void guardar(ActionEvent ae){
        String msg=getMensajeError();
        if(msg.equals("")){
            GestorCriteriosDB.getInstance().guardarFormula(criterio, formula);
            styleMesage="msg";
            FacesMessage faces=new FacesMessage("LA FUNCION SE GUARDO CORRECTAMENTE");
            FacesContext.getCurrentInstance().addMessage(null,faces);
        }else{
            styleMesage="error";
            FacesMessage faces=new FacesMessage("FUNCION MAL REALIZADA NO SE GUARDARAN CAMBIOS", "FORMULA MAL REALIZADA NO SE GUARDARAN CAMBIOS");
            FacesContext.getCurrentInstance().addMessage(null,faces);
        }
    }
    public String getStyleMsg(){
        return styleMesage;
    }
}
